home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / apilot.lha / APilot / APilot_Ser / cannons.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-03  |  5.0 KB  |  204 lines

  1. /*************************************************************************
  2.  * 
  3.  * cannon.c -- Cannon handling functions.
  4.  *
  5.  *-------------------------------------------------------------------------
  6.  * Authors: Casper Gripenberg  (casper@alpha.hut.fi)
  7.  *          Kjetil Jacobsen  (kjetilja@stud.cs.uit.no)
  8.  *
  9.  */
  10.  
  11. /*--------------------------------------------------------------------------*/
  12.  
  13. #include <stdlib.h>
  14. #include <exec/types.h>
  15. #include <libraries/dos.h>
  16.  
  17. #include "common.h"
  18.  
  19. #include "main_protos.h"
  20. #include "lists_protos.h"
  21. #include "points_protos.h"
  22. #include "cannon_protos.h"
  23.  
  24. /*--------------------------------------------------------------------------*/
  25.  
  26. #define IN_RANGE(o1, o2, r) (abs((o1)->pos.x-(o2)->pos.x)<(r)     \
  27.                              && abs((o1)->pos.y-(o2)->pos.y)<(r))
  28.  
  29. extern int sina[];
  30. extern int cosa[];
  31.  
  32. extern AWorld World;
  33.  
  34. /*--------------------------------------------------------------------------*/
  35.  
  36. /*
  37.  * alloc_cannon -- Allocate a new cannon and add it to the world cannon list.
  38.  *
  39.  */                 
  40. ACannon *
  41. alloc_cannon(int map_x, int map_y, cdir_t direction)
  42. {
  43.   ACannon *cannon;
  44.  
  45.   if ( (cannon = (ACannon *) malloc(sizeof(ACannon))) == NULL )
  46.     cleanExit( RETURN_WARN, "** Unable to get memory for cannons.\n" );
  47.  
  48.   switch (direction) {
  49.     case C_UP:
  50.       cannon->pos.x = MAP_BLOCKSIZE * map_x + MAP_BLOCKSIZE/2;
  51.       cannon->pos.y = MAP_BLOCKSIZE * map_y + MAP_BLOCKSIZE - CAN_HEIGHT/2;
  52.       break;
  53.     case C_DN:    
  54.       cannon->pos.x = MAP_BLOCKSIZE * map_x + MAP_BLOCKSIZE/2;
  55.       cannon->pos.y = MAP_BLOCKSIZE * map_y + CAN_HEIGHT/2;
  56.       break;
  57.     case C_LF:    
  58.       cannon->pos.x = MAP_BLOCKSIZE * map_x + MAP_BLOCKSIZE - CAN_HEIGHT/2; 
  59.       cannon->pos.y = MAP_BLOCKSIZE * map_y + MAP_BLOCKSIZE/2;
  60.       break;
  61.     case C_RG:    
  62.       cannon->pos.x = MAP_BLOCKSIZE * map_x + CAN_HEIGHT/2; 
  63.       cannon->pos.y = MAP_BLOCKSIZE * map_y + MAP_BLOCKSIZE/2;
  64.       break;
  65.     default:
  66.       /* NOTREACHED */
  67.       break;
  68.   }  
  69.  
  70.   cannon->mapos.x   = map_x;
  71.   cannon->mapos.y   = map_y;
  72.   cannon->cdir      = direction;
  73.   cannon->cstate    = INACTIVE;
  74.   cannon->deadcount = 0;
  75.   cannon->firedelay = 0;
  76.  
  77.   /*
  78.    * Add cannon to the world cannon list.
  79.    */
  80.   cannon->next = World.cannons->next;
  81.   World.cannons->next = cannon;
  82.     
  83.   return cannon;
  84. }
  85.  
  86. /*--------------------------------------------------------------------------*/
  87.  
  88. /*
  89.  * Kills a cannon.
  90.  *
  91.  */
  92. void
  93. kill_cannon( ACannon *cannon )
  94. {
  95.   cannon->cstate    = DEAD;
  96.   cannon->deadcount = CAN_DEDTIME;
  97.  
  98.   add_explosion(cannon->pos.x, cannon->pos.y);
  99. }
  100.  
  101. /*--------------------------------------------------------------------------*/
  102.  
  103. /*
  104.  * update_cannons -- Checks on dead cannons and makes active cannons
  105.  *                   fire at player.
  106.  */
  107. void
  108. update_cannons( AShip *ship, UWORD nframes )
  109. {
  110.   ACannon *cannon = World.cannons->next;
  111.  
  112.   while (cannon->next != cannon)
  113.   {
  114.     switch (cannon->cstate) {
  115.       case DEAD:
  116.         cannon->deadcount -= nframes;
  117.         if (cannon->deadcount <= 0)
  118.           cannon->cstate = INACTIVE;
  119.         break;
  120.       case ACTIVE:
  121.         if (!IN_RANGE(ship, cannon, 300)) {
  122.           cannon->cstate = INACTIVE;       
  123.           break;
  124.         } 
  125.         cannon->firedelay -= nframes;
  126.         if (cannon->firedelay <= 0) {
  127.           cannon->firedelay = CAN_FIREDELAY + 
  128.                               ((rand()%(CAN_FDSPREAD*2))-CAN_FDSPREAD);
  129.           fire_cannon(cannon);
  130.           break;
  131.         }
  132.         break;
  133.       case INACTIVE:
  134.         if (IN_RANGE(ship, cannon, 300))
  135.           cannon->cstate = ACTIVE;
  136.         break;
  137.       default:
  138.         /* NOTREACHED */
  139.         break;
  140.     }
  141.     cannon = cannon->next;
  142.   }
  143. }
  144.  
  145. /*--------------------------------------------------------------------------*/
  146.  
  147. /*
  148.  * fire_cannon -- Fires the cannon in a random direction.
  149.  *
  150.  */
  151. void
  152. fire_cannon( ACannon *cannon )
  153. {
  154.   int pos_x, pos_y;
  155.   int angle, speed;
  156.  
  157.   APoint *shot;
  158.  
  159.   if ((shot = alloc_point()) == NULL)
  160.     return;
  161.  
  162.   pos_x = cannon->pos.x;  
  163.   pos_y = cannon->pos.y;
  164.   angle = (rand() % (CAN_FIREANGLE*2)) - CAN_FIREANGLE;
  165.   speed = PRECS*2 + (rand()%(PRECS + PRECS/2));
  166.   switch (cannon->cdir) {
  167.     case C_UP:
  168.       pos_y -= CAN_HEIGHT/2 + 2;
  169.       angle = (180 + angle) % 360;
  170.       break;
  171.     case C_DN:
  172.       pos_y += CAN_HEIGHT/2 + 2;
  173.       angle = (360 + angle) % 360;      
  174.       break;
  175.     case C_LF:
  176.       pos_x -= CAN_HEIGHT/2 + 2;
  177.       angle = (270 + angle) % 360;
  178.       break;
  179.     case C_RG:
  180.       pos_x += CAN_HEIGHT/2 + 2;
  181.       /*
  182.        * 360 + 90 -> just to be sure we won't get negative values if
  183.        * CAN_FIREANGLE happens to be big.
  184.        */
  185.       angle = (360+90 + angle) % 360;
  186.       break;
  187.     default:
  188.       /* NOTREACHED */
  189.       break;
  190.   }
  191.  
  192.   shot->pos.x = pos_x;
  193.   shot->pos.y = pos_y;
  194.   shot->xvel  = (speed * sina[angle]) >> SHFTPR;
  195.   shot->yvel  = (speed * cosa[angle]) >> SHFTPR;
  196.   shot->life  = CAN_SHOTLIFE + ((rand() % 20) - 10);
  197.   shot->type  = CANNON_SHOT;
  198.   shot->mass  = CAN_SHOTMASS;
  199.   shot->color = WHITE;
  200.  
  201. }
  202.   
  203. /*--------------------------------------------------------------------------*/
  204.